#include "MTwister.h"

//using namespace std;

MTrng::MTrng(int seed){
	index = 0;
	MT[0] = seed;
	for (int i = 1; i < 624; i++){
		MT[i] = 0xffffffff & (0x6c078965 * (MT[i-1] ^ (MT[i-1] >> 30)) + 1);
	}
}

void MTrng::generate_numbers(){
	for (int i = 0; i < 624; i++){
		int y = (MT[i] & 0x80000000) + (MT[(i+1) % 624] & 0x7fffffff);
		MT[i] = MT[(i + 397) % 624] ^ (y >> 1);
		if ((y % 2) != 0){
			MT[i] ^= (0x9908b0df);
		}
	}
}

int MTrng::getNext(){
	if (index == 0){
		generate_numbers();
	}

	int y = MT[index];
	y ^= (y >> 11);
	y ^= ((y << 7) & 0x9d2c5680);
	y ^= ((y << 15) & 0xefc60000);
	y ^= (y >> 18);

	index = (index + 1) % 624;
	return y;
}

int MTrng::getNext(int min, int max){
	return getNext() % (max - min + 1) + min;
}

int MTrng::getNext(int min){
	return getNext() % (0xffffffff - min + 1) + min;
}